//
//  RNTPolyvLive.m
//  rzc_app
//
//  Created by 孙磊 on 2019/8/30.
//  Copyright © 2019 Facebook. All rights reserved.
//

#import "RNTPolyvLive.h"
#import "LivePlayerViewController.h"
#import "PLVLiveWarmPlayer.h"
#import "PLVLivePlayerController.h"
#import "ZJZDanMu.h"
#import "PLVUtils.h"
#import <React/RCTConvert.h>
#import <React/RCTBridgeModule.h>
#import <React/RCTEventDispatcher.h>
#import <React/UIView+React.h>
@interface RNTPolyvLive ()
@property (nonatomic, strong) ZJZDanMu *danmuLayer;  // 弹幕
@property (nonatomic, strong) PLVLivePlayerController *livePlayer;          // PLV播放器
@property (nonatomic, strong) PLVLiveWarmPlayer *warmPlayer;          // PLV播放器
/// 当前的直播流状态
@property (nonatomic, assign, readonly) PLVLiveStreamState streamState;
@property (nonatomic, assign) NSUInteger channelId;
@property (nonatomic, strong) NSString *stream;
@property (nonatomic, getter=isShowCover) BOOL showCover;
@property (nonatomic, assign) BOOL fullScreen;
@property (nonatomic, assign) BOOL canOrientation;
@end

@implementation RNTPolyvLive
{
  /* Required to publish events */
  RCTEventDispatcher *_eventDispatcher;
  BOOL showdanmu;
  NSTimer *_liveStatusTimer;
}
/*
 // Only override drawRect: if you perform custom drawing.
 // An empty implementation adversely affects performance during animation.
 - (void)drawRect:(CGRect)rect {
 // Drawing code
 }
 */
- (instancetype)initWithEventDispatcher:(RCTEventDispatcher *)eventDispatcher
{
  self = [super init];
  if (self) {
    _eventDispatcher = eventDispatcher;
    
  }
  return self;
}
- (void)updateLiveChanel{
  if (self.liveChannel != nil) {
    _channelId = self.liveChannel.channelId.unsignedIntegerValue;
    _streamState = PLVLiveStreamStateUnknown;
    [self configObserver];
    [self configOrientation];
    [self addTimerEvents];
  } else {
    if (self.vidWarmVideo) {
      [self initializewarmPlayer];
      if (self.onPlayLiveEvent) {
        self.onPlayLiveEvent(@{@"key":@"streamstate", @"value": @"VIDEO" });
      }
    }
  }
}

- (void)layoutSubviews
{
  [super layoutSubviews];
  if( _livePlayer )
  {
    //    _livePlayer.view.frame = self.bounds;
    //    _danmuLayer.frame = CGRectMake(0, 20, CGRectGetWidth(self.bounds), CGRectGetHeight(self.bounds) -20);
  }
  if( _warmPlayer )
  {
    //    _warmPlayer.frame = self.bounds;
  }
  else
  {
    [CATransaction begin];
    [CATransaction setAnimationDuration:0];
    [CATransaction commit];
  }
}
- (void)dealloc {
  [self freeLiveStatusTimer];
  [self freeOrientation];
  [self shutdownPlayer];
  RCTLog(@"-[%@ %@]",NSStringFromClass([self class]),NSStringFromSelector(_cmd));
  [[NSNotificationCenter defaultCenter] removeObserver:self];
  [[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleDefault animated:YES];
}


#pragma mark - Public
- (void)setCanorientation:(BOOL)canorientation{
  self.canOrientation = canorientation;
}
- (void)setPaused:(BOOL)paused{
  RCTLog(@"setPaused%d",paused);
  if(_livePlayer){
    if (paused) {
      [_livePlayer pauseButtonClick];
    }else{
      [_livePlayer playButtonClick];
    }
  }
  if(_warmPlayer){
    if (paused) {
      [_warmPlayer pause];
    }else{
      [_warmPlayer play];
    }
  }
}

- (void)setFullscreen:(BOOL)fullscreen{
  RCTLog(@"setFullscreen%d",fullscreen);
  if ( self.fullScreen != fullscreen) {
    if (fullscreen) {
      [self setOrientation:UIInterfaceOrientationLandscapeRight];
    }else{
      [self setOrientation:UIInterfaceOrientationPortrait];
    }
  }
  
}

- (void)setShowdanmu:(BOOL)showdanmu{
  RCTLog(@"setShowdanmu%d",showdanmu);
  if (_danmuLayer) {
    [_danmuLayer setHidden:!showdanmu];
  }
}
- (void)setDanmumsg:(NSString*)danmumsg{
  RCTLog(@"setDanmumsg%@",danmumsg);
  if (_danmuLayer) {
    [_danmuLayer insertDML:danmumsg];
  }
}
- (void)setDefinitions:(NSString *)definition{
  RCTLog(@"setDefinitions%@",definition);
  if(_livePlayer){
    [_livePlayer setDefinitions:definition];
  }
}



#pragma mark - Public
- (void)freePlayer{
  @try {
    [self freeLiveStatusTimer];
    [self freeOrientation];
    [self shutdownPlayer];
  } @catch (NSException *exception) {
    RCTLog(@"shutdown failure, exception name: %@, exception reason: %@",exception.name,exception.reason);
  }
}
- (void)configObserver {
  __weak typeof(self)weakSelf = self;
//  [PLVLiveAPI getStreamStatusWithChannelId:self.channelId stream:self.stream completion:^(PLVLiveStreamState streamState, NSString *mode) {
//    if (streamState == PLVLiveStreamStateNoStream) {
//      weakSelf.warmPlayer = [weakSelf initializewarmPlayer];
//    } else if (streamState == PLVLiveStreamStateLive) {
//        weakSelf.livePlayer = [weakSelf initializeLivePlayer];
//    }
//  } failure:^(PLVLiveErrorCode errorCode, NSString *description) {
//    [weakSelf.livePlayer play];
//  }];
  
  // 注册播放器通知
  [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(livePlayerReconnectNotification:) name:PLVLivePlayerReconnectNotification object:nil];
  [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(livePlayerWillChangeToFullScreenNotification) name:PLVLivePlayerWillChangeToFullScreenNotification object:nil];
  [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(livePlayerWillExitFullScreenNotification) name:PLVLivePlayerWillExitFullScreenNotification object:nil];
}
- (PLVLiveWarmPlayer *)initializewarmPlayer {
  [self shutdownPlayer];
  _warmPlayer = [[PLVLiveWarmPlayer alloc] initWithVid:self.vidWarmVideo displayView:self];
  __weak typeof(self)weakSelf = self;
//  [_warmPlayer setCoverImageBeClickedBlock:^(NSString * _Nonnull coverHref) {
//    RCTLog(@"setCoverImageBeClickedBlock%@",coverHref);
//    weakSelf.onPlayLiveEvent(@{@"key":@"coverHref", @"value":coverHref});
//  }];
  
  [_warmPlayer setPlayCoverBegin:^{
    RCTLog(@"setPlayCoverBegin");
    if (weakSelf.onPlayLiveEvent) {
      weakSelf.onPlayLiveEvent(@{@"key":@"paused", @"value": @(NO)});
    }
  }];
  [_warmPlayer setPlayCoverEnd:^{
    RCTLog(@"setPlayCoverEnd");
    if (weakSelf.onPlayLiveEvent) {
      weakSelf.onPlayLiveEvent(@{@"key":@"paused", @"value": @(YES)});
    }
  }];
  _showCover = YES;
  return _warmPlayer;
}
- (PLVLivePlayerController *)initializeLivePlayer {
  [self shutdownPlayer];
  _livePlayer = [[PLVLivePlayerController alloc] initWithChannel:_liveChannel displayView:self];
  if (self.onPlayLiveEvent) {
    self.onPlayLiveEvent(@{@"key":@"paused", @"value": @(NO)});
  }
  //[IJKFFMoviePlayerController setLogLevel:k_IJK_LOG_INFO];    // 日志等级
  __weak typeof(self)weakSelf = self;
  [_livePlayer setPlayerInfoBlock:^(NSString *info){
    RCTLog(@"setPlayerInfoBlock%@",info);
  }];
  [_livePlayer setCoverImageBeClickedBlock:^(NSString *coverHref) {
    if (weakSelf.onPlayLiveEvent) {
      weakSelf.onPlayLiveEvent(@{@"key":@"coverHref", @"value": coverHref});
    }
  }];
  [_livePlayer setPlayLiveBegin:^{
    RCTLog(@"setPlayCoverBegin");
    if (weakSelf.onPlayLiveEvent) {
      weakSelf.onPlayLiveEvent(@{@"key":@"paused", @"value": @(NO)});
    }
  }];
  [_livePlayer setPlayLiveEnd:^{
    RCTLog(@"setPlayCoverEnd");
    if (weakSelf.onPlayLiveEvent) {
      weakSelf.onPlayLiveEvent(@{@"key":@"paused", @"value": @(YES)});
    }
  }];
  [self addSubview:self.danmuLayer]; // 添加弹幕层
  _showCover = NO;
  return _livePlayer;
}
- (void)shutdownPlayer {
  if (_livePlayer) {
    [_livePlayer clearPlayer];
    _livePlayer = nil ;
  }
  if (_warmPlayer) {
    [_warmPlayer clearPlayer];
    _warmPlayer = nil ;
  }
}

- (ZJZDanMu *)danmuLayer {
  if (!_danmuLayer) {
    _danmuLayer = [[ZJZDanMu alloc] initWithFrame:CGRectMake(0, 20, CGRectGetWidth(self.bounds), CGRectGetHeight(self.bounds) -20)];
  }
  return _danmuLayer;
}

#pragma mark Notifications

// 直播播断流后重新连接时创建一个新的播放器
- (void)livePlayerReconnectNotification:(NSNotification *)notification {
  RCTLog(@"livePlayerReconnectNotification");
  __weak typeof(self)weakSelf = self;
  [PLVLiveAPI loadChannelInfoRepeatedlyWithUserId:_userId channelId:_channelId completion:^(PLVLiveChannel *channel) {
    weakSelf.liveChannel = channel;
    NSDictionary *userInfo = notification.userInfo;
    if (userInfo && userInfo[@"definition"]) {
      [weakSelf.liveChannel updateDefaultDefinitionWithDefinition:userInfo[@"definition"]];
    }
    weakSelf.livePlayer = [weakSelf initializeLivePlayer];
    [weakSelf.livePlayer play];
  } failure:^(PLVLiveErrorCode errorCode, NSString *description) {
    RCTLog(@"errorCode:%ld, description:%@",errorCode,description);
  }];
}

- (void)livePlayerWillChangeToFullScreenNotification {
  RCTLog(@"将要全屏啦");
  //  [self.view endEditing:YES];
}

- (void)livePlayerWillExitFullScreenNotification {
  RCTLog(@"将要退出全屏啦");
}
#pragma mark timer
- (void)addTimerEvents {
  [self freeLiveStatusTimer];
  _liveStatusTimer = [NSTimer scheduledTimerWithTimeInterval:8.0 target:self
                                                    selector:@selector(onTimeCheckLiveStreamState) userInfo:nil repeats:YES];
  [_liveStatusTimer fire];
  //   timeout logic
}
- (void)onTimeCheckLiveStreamState {
  //RCTLog(@"playbackState:%ld,loadState:%ld",self.playbackState,self.loadState);
  __weak typeof(self)weakSelf = self;
  [PLVLiveAPI isLiveWithStream:self.liveChannel.stream completion:^(PLVLiveStreamState streamState) {
    [weakSelf setStreamState:streamState];
  } failure:^(PLVLiveErrorCode errorCode, NSString *description) {
    RCTLog(@"获取流状态失败 %@",description);
  }];
}

- (void)setStreamState:(PLVLiveStreamState)streamState {
  RCTLog(@"setStreamState%zi",streamState);
  if (streamState == PLVLiveStreamStateNoStream) {
    if (self.onPlayLiveEvent && self.vidWarmVideo) {
      self.onPlayLiveEvent(@{@"key":@"streamstate", @"value": @"VIDEO" });
    }
    if (!self.warmPlayer ) {
      [self initializewarmPlayer];
    }
    if (_streamState == PLVLiveStreamStateLive) {
      [self setOrientation:UIInterfaceOrientationPortrait];
    }
  }else if (streamState == PLVLiveStreamStateLive ) {
    NSTimeInterval now = [[NSDate date] timeIntervalSince1970];
    NSTimeInterval start = [self.startTime doubleValue];
    if (start-now > 5) {
      _streamState = PLVLiveStreamStateNoStream;
      if (self.livePlayer) {
        [self.livePlayer stop];
      }
      
      if (self.onPlayLiveEvent && self.vidWarmVideo) {
        self.onPlayLiveEvent(@{@"key":@"streamstate", @"value":  @"VIDEO"});
      }
      RCTLog(@"有流 未开始");
      return;
    }
    RCTLog(@"有流 已开始");
    if ( !self.livePlayer || _streamState == PLVLiveStreamStateNoStream) {
      [[NSNotificationCenter defaultCenter] postNotificationName:PLVLivePlayerReconnectNotification object:self];
    }
    if (self.onPlayLiveEvent) {
      self.onPlayLiveEvent(@{@"key":@"streamstate", @"value": @"LIVE"});
    }
  }
  _streamState = streamState;
}

- (void)freeLiveStatusTimer {
  if (_liveStatusTimer) {
    [_liveStatusTimer invalidate];
    _liveStatusTimer = nil;
  }
}

#pragma mark device rotation
- (void)configOrientation {
  [[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
  [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(deviceOrientationDidChange) name:UIDeviceOrientationDidChangeNotification object:nil];
}
- (void)freeOrientation {
  [[UIDevice currentDevice] endGeneratingDeviceOrientationNotifications];
}
- (void)deviceOrientationDidChange {
  UIInterfaceOrientation interfaceOrientation = (UIInterfaceOrientation)[[UIDevice currentDevice] orientation];
  switch (interfaceOrientation) {
    case UIInterfaceOrientationPortrait:
      self.fullScreen = NO;
      RCTLog(@"deviceOrientationDidChange  -->UIInterfaceOrientationPortrait%ld",(long)interfaceOrientation);
      if (_livePlayer) {
        [_livePlayer setOrientationPortrait];
      }
      if (_warmPlayer) {
        [_warmPlayer setOrientationPortrait];
//        [_warmPlayer switchToFullScreen:NO];
      }
      if (self.onPlayLiveEvent) {
        self.onPlayLiveEvent(@{@"key":@"fullscreen", @"value": @(NO)});
      }
      break;
    case UIInterfaceOrientationLandscapeLeft:
    case UIInterfaceOrientationLandscapeRight:
      if (!self.canOrientation) {
        return;
      }
      self.fullScreen = YES;
      RCTLog(@"deviceOrientationDidChange  -->UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight");
      if (_livePlayer) {
        [_livePlayer setOrientationLandscape];
      }
      if (_warmPlayer) {
        [_warmPlayer setOrientationLandscape];
//        [_warmPlayer switchToFullScreen:YES];
      }
      if (self.onPlayLiveEvent) {
         self.onPlayLiveEvent(@{@"key":@"fullscreen", @"value": @(YES)});
      }
    default:
      break;
  }
}
- (void)setOrientation:(UIInterfaceOrientation)orientation {
  RCTLog(@"setOrientation  orientation%ld",(long)orientation);
  if ([[UIDevice currentDevice] respondsToSelector:@selector(setOrientation:)]) {
    SEL selector = NSSelectorFromString(@"setOrientation:");
    NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:[UIDevice instanceMethodSignatureForSelector:selector]];
    [invocation setSelector:selector];
    [invocation setTarget:[UIDevice currentDevice]];
    int val = orientation;
    [invocation setArgument:&val atIndex:2];
    [invocation invoke];
  }
}
@end
